(* ECHANTILLONNAGE DU RELIEF ET CREATION DU FICHIER .OBJ CONTENANT
   LES COORDONNEES *)
    
let interval = ImageProcessing.interval
let nb_vertex = ref 0
let nb_face = ref 0
let vertex = ref []
let face = ref []

(* donne les coordonnees standard a partir des coordonnees
   d'echantillonnage *)
let get_xy (x,y) =
  let x = (x * !interval)/2 in
  let y = (y * !interval)/2 in
  (x,y)
    
(* donne la taille d'echantillonage a partir de la taille
   standards *)
let get_sample_wh (w,h) =
  let w = (w / !interval) in
  let h = (h / !interval) in
  (w,h)

let max (a,b) =
  if a >= b then a else b

(* donne une estimation de l'altitude *)
let get_altitude_complex (x,y) map =
  let (x,y) = get_xy (x,y) in
  let (width,height) = SdlFunction.get_dims map in
  let point_color = Sdlvideo.get_pixel_color map x y in
  let color1 = ref (-1,-1,-1) in
  let color2 = ref (-1,-1,-1) in
  let is_out (w,h) =
    (w <= 0 || w >= width - 1 || h <= 0 || h >= height - 1) in
  let search_left (xl,yl) =
    if is_out (xl,yl) then
      if !color1 = (-1,-1,-1) then
	color1 := point_color
      else
	color2 := point_color
    else
      let left_color = Sdlvideo.get_pixel_color map (xl-1) yl in
      if left_color <> point_color then
	if !color1 = (-1,-1,-1) then
	  color1 := left_color
	else
	  color2 := left_color
  in
  let search_right (xr,yr) =
    if is_out (xr,yr) then
      if !color1 = (-1,-1,-1) then
	color1 := point_color
      else
	color2 := point_color
    else
      let right_color = Sdlvideo.get_pixel_color map (xr+1) yr in
      if right_color <> point_color then
	if !color1 = (-1,-1,-1) then
          color1 := right_color
	else
          color2 := right_color
  in
  let search_up (xu,yu) =
    if is_out (xu,yu) then
      if !color1 = (-1,-1,-1) then
	color1 := point_color
      else
	color2 := point_color
    else
      let up_color = Sdlvideo.get_pixel_color map xu (yu-1) in
      if up_color <> point_color then
	if !color1 = (-1,-1,-1) then
          color1 := up_color
	else
          color2 := up_color
  in
  let search_down (xd,yd) =
    if is_out (xd,yd) then
      if !color1 = (-1,-1,-1) then
	color1 := point_color
      else
	color2 := point_color
    else
      let down_color = Sdlvideo.get_pixel_color map xd (yd+1) in
      if down_color <> point_color then
	if !color1 = (-1,-1,-1) then
          color1 := down_color
	else
          color2 := down_color
  in
  search_up (x,y);
  search_right (x,y);
  search_down (x,y);
  search_left (x,y);
  let n = ref 1 in
  while !color2 <> (-1,-1,-1) do
    search_up (x,y-(!n));
    for i = 0 to !n do
      search_right (x+i,y+(!n)-i);
    done;
    search_right (x+(!n),y);
    for i = 0 to !n do
      search_down (x+(!n)-1,y+i);
    done;
    search_down (x,y+(!n));
    for i = 0 to !n do
      search_left (x-i,y-(!n)+i);
    done;
    search_left (x-(!n),y);
    for i = 0 to !n do
      search_up (x-(!n)+1,y-i);
    done;
    n := !n + 1;
  done;
  let a1 = ColorList.get_altitude !color1 in
  let a2 = ColorList.get_altitude !color2 in
  let a = max(a1,a2) in
  let cur_a = ColorList.get_altitude point_color in
  let (r,v,b) = !color1 in
  print_string (string_of_int r^" "^string_of_int v
		^" "^string_of_int b^"\n");
  ((float_of_int a) +. (float_of_int cur_a)) /. 2.
    
(* obtient l'altitude a des coordonnees donnees *)
let get_altitude (x,y) map =
  let (x,y) = get_xy (x,y) in
  let color = Sdlvideo.get_pixel_color map x y in
  float_of_int (ColorList.get_altitude color)

(* genere la liste des faces dans map.obj *)
let creat_face file (width,height) =
  begin
    let w = ref 0 in
    let h = ref 0 in
    let n = ref 1 in
    while (!h < height) do
      while (!w < width) do
	let up_left = string_of_int !n in
	let up_right = string_of_int (!n + 1) in
	let mid = string_of_int (!n + width + 1) in
	let down_left = string_of_int (!n + 2 * width + 1) in
	let down_right = string_of_int (!n + 2 * width + 2) in
	let face1 = "f " ^ up_left ^ " " ^ up_right ^
	  " " ^ mid ^ "\n" in
	face := (!n,!n+1,!n+width+1)::(!face);
	let face2 = "f " ^ up_left ^ " " ^ mid ^
	  " " ^ down_left ^ "\n" in
	face := (!n,!n+width+1,!n+2*width+1)::(!face);
	let face3 = "f " ^ down_left ^ " " ^ mid ^
	  " " ^ down_right ^ "\n" in
	face := (!n+2*width+1,!n+width+1,!n+2*width+2)::(!face);
	let face4 = "f " ^ down_right ^ " " ^ mid ^
	  " " ^ up_right ^ "\n" in
	face := (!n+2*width+2,!n+width+1,!n+1)::(!face);
	output_string file face1;
	output_string file face2;
	output_string file face3;
	output_string file face4;
	n := !n + 1;
	w := !w + 1;
	nb_face := !nb_face + 4;
      done;
      w := 0;
      h := !h + 1;
      n := !n + width + 1;
    done;
  end

(* genere la liste des points dans map.obj *)
let creat_point file map (width,height) =
  let h = ref 0 in
  let w = ref 0 in
  let i = ref 1 in
  begin
    while (!h < 2 * height + 1) do
      while (!w < 2 * width + 1) do
	let z = get_altitude (!w,!h) map in
	let point = "v " ^ string_of_int !w ^ " " ^
	  string_of_float z ^ " " ^ string_of_int (!h) ^ "\n" in
	output_string file point;
	w := !w + 2;
	vertex := (float_of_int !w, z,float_of_int !h)
	::(!vertex);
	nb_vertex := !nb_vertex + 1;
      done;
      h := !h + 1;
      w := !i;
      if (!i = 1) then
      i := 0
      else
      i := 1;
    done;
  end

(* cree un fichier obj representant la carte *)
let create_obj map =
  begin
    let file = open_out "map.obj" in
    let (real_width,real_height) = SdlFunction.get_dims map in
    let(real_width,real_height) = 
      (((real_width/(!interval))*(!interval)),
       ((real_height/(!interval))*(!interval))) in
    let (width,height) = get_sample_wh (real_width,real_height) in
    output_string file "o Map\n";
    creat_point file map (width,height);
    creat_face file (width,height);
    close_out file;
  end

(* crée le fichier "map.obj" *)
let sample () =
  begin
    let map = Sdlloader.load_image !ImageProcessing.path in
    create_obj map;
  end
